package com.iqiyi.pps.epg.web.timer;

import com.iqiyi.pps.epg.core.model.channel.ChannelBase;
import com.iqiyi.pps.epg.core.model.channel.ChannelConfig;
import com.iqiyi.pps.epg.core.model.program.ProgramRecent;
import com.iqiyi.pps.epg.core.model.program.ProgramRecentCollect;
import com.iqiyi.pps.epg.core.service.channel.ChannelService;
import com.iqiyi.pps.epg.core.service.program.ProgramService;
import com.iqiyi.pps.epg.core.utils.DateTimeUtil;

import com.iqiyi.pps.epg.core.utils.SendMailUtils;
import com.iqiyi.pps.epg.core.utils.SendMsgUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * Created by karkarrotxu on 2015/7/24.
 */
public class ProgramCheckTrigger {
    private static final String PROGRAM_CHECK_TITLE = "节目单每日检查";

    private static final String MSG_FORMAT_PRE = "总计有 ";
    private static final String MSG_FORMAT_NO_DATA = "%s个频道没有3天内节目单!";
    private static final String MSG_FORMAT_NO_SYNC = "%s有%s个节目没有同步奇谱!";
    private static final String MAIL_FORMAT_PRE = "频道:%s |";
    private static final String MAIL_FORMAT_NO_DATA = " %s没有节目单!";
    private static final String MAIL_FORMAT_NO_SYNC = " %s有%s个节目没有同步奇谱!";

    private static Logger logger = LoggerFactory.getLogger(ProgramCheckTrigger.class);

    @Autowired
    private ChannelService channelService;
    @Autowired
    private ProgramService programService;

    public void task() {
        logger.info("[ProgramCheckTrigger][task] begin");
        long startTime = System.currentTimeMillis();
        List<Criterion> list = new ArrayList<Criterion>();
        list.add(Restrictions.eq("liveType", 1));
        list.add(Restrictions.eq("isEnable", 1));
        list.add(Restrictions.eq("formal", 1));
        List<ChannelBase> baseList = channelService.findChannelBaseList(list);
        List<Long> idList = new ArrayList<>();
        for (ChannelBase base : baseList) {
            idList.add(base.getId());
        }
        if (idList.size() == 0) {
            logger.info("[ProgramCheckTrigger][task] no ct data");
            return;
        }
        Map<Long, ProgramRecentCollect> map = new HashMap<>();
        ProgramRecentCollect prc = null;
        for (ChannelBase channelBase : baseList) {
            prc = new ProgramRecentCollect();
            prc.setChannelId(channelBase.getId());
            prc.setName(channelBase.getName());
            map.put(prc.getChannelId(), prc);
        }
        long checkTime = System.currentTimeMillis();
        try {
            checkRecentData(checkTime, idList, map);
        } catch (Exception e) {
            logger.warn("[task][checkRecentData]", e);
        }
        try {
            checkSyncData(checkTime, idList, map);
        } catch (Exception e) {
            logger.warn("[task][checkSyncData]", e);
        }
        String mailContent = doMailFormat(checkTime, map);
        String msgContent = doMsgFormat(checkTime, map);
        logger.info("msgContent:" + msgContent);
        if (mailContent.length() > 0) {
            sendMail(mailContent);
        }
        if (msgContent.length() > 0) {
            sendMsg(msgContent);
        }

        long endTime = System.currentTimeMillis();
        logger.info("[ProgramCheckTrigger][task] end : " + (endTime - startTime));
    }

    private String doMailFormat(long checkTime, Map<Long, ProgramRecentCollect> map) {
        StringBuffer sb = new StringBuffer();
        StringBuffer tempSb = null;
        boolean needRecord = false;
        String checkDate = DateTimeUtil.transShortFormat(checkTime);
        String dates = null;
        for (ProgramRecentCollect collect : map.values()) {
            needRecord = false;
            tempSb = new StringBuffer();
            tempSb.append(String.format(MAIL_FORMAT_PRE, collect.getName()));
            if (collect.getDateList().size() > 0) {
                needRecord = true;
                dates = collect.getDateList().toString();
                tempSb.append(String.format(MAIL_FORMAT_NO_DATA, dates.substring(1, dates.length() - 1)));
            }
            if (collect.getNoSyncNum() > 0) {
                needRecord = true;
                tempSb.append(String.format(MAIL_FORMAT_NO_SYNC, checkDate, collect.getNoSyncNum() + ""));
            }
            if (needRecord) {
                sb.append(tempSb.toString() + "<br>");
            }
        }
        return sb.toString();
    }

    private String doMsgFormat(long checkTime, Map<Long, ProgramRecentCollect> map) {
        StringBuffer sb = new StringBuffer();
        int channelNum = 0;
        int noSyncNum = 0;
        boolean needRecord = false;
        String checkDate = DateTimeUtil.transShortFormat(checkTime);
        for (ProgramRecentCollect collect : map.values()) {
            if (collect.getDateList().size() > 0) {
                channelNum++;
            }
            if (collect.getNoSyncNum() > 0) {
                noSyncNum += collect.getNoSyncNum();
            }
        }
        StringBuffer tempSb = null;
        tempSb = new StringBuffer(MSG_FORMAT_PRE);
        if (channelNum > 0) {
            needRecord = true;
            tempSb.append(String.format(MSG_FORMAT_NO_DATA, channelNum + ""));
        }
        if (noSyncNum > 0) {
            needRecord = true;
            tempSb.append(String.format(MSG_FORMAT_NO_SYNC, checkDate, noSyncNum + ""));
        }
        if (needRecord) {
            sb.append(tempSb.toString());
        }

        return sb.toString();
    }

    public void checkRecentData(long checkTime, List<Long> idList, Map<Long, ProgramRecentCollect> map) {
        logger.info("[ProgramCheckTrigger][checkRecentData] begin");
        String dateMin = DateTimeUtil.transShortFormat(checkTime);
        String date2 = DateTimeUtil.transShortFormat(checkTime + 86400000L);
        String dateMax = DateTimeUtil.transShortFormat(checkTime + 86400000L * 2);
        List<ProgramRecent> recentList = programService.findRecent(idList, dateMin + " 00:00:00", dateMax + " 23:59:59", false);
        Map<String, Integer> checkMap = new HashMap<String, Integer>();
        for (Long channelId : idList) {
            checkMap.put(channelId + "_" + dateMin, 0);
            checkMap.put(channelId + "_" + date2, 0);
            checkMap.put(channelId + "_" + dateMax, 0);
        }
        for (ProgramRecent recent : recentList) {
            if (recent.getCountNum() > 0) {
                checkMap.remove(recent.getFatherId() + "_" + recent.getDate());
            }
        }
        if (checkMap.size() > 0) {
            String[] idDate = null;
            Set<String> idSet = new HashSet<String>();
            List<String> sortList = new ArrayList<String>(checkMap.keySet());
            Collections.sort(sortList);
            for (String key : sortList) {
                idDate = key.split("_");
                map.get(Long.valueOf(idDate[0])).addDate(idDate[1]);
            }
        }
    }

    public void checkSyncData(long checkTime, List<Long> idList, Map<Long, ProgramRecentCollect> map) {
        logger.info("[ProgramCheckTrigger][checkSyncData] begin");
        String dateMin = DateTimeUtil.transShortFormat(checkTime);
        List<ProgramRecent> recentList = programService.findRecent(idList, dateMin + " 00:00:00", dateMin + " 23:59:59", true);
        long totalNum = 0;
        if (recentList.size() > 0) {
            for (ProgramRecent recent : recentList) {
                if (recent.getCountNum() > 0) {
                    programService.logoutNoSyncRecent(recent.getFatherId(),dateMin + " 00:00:00", dateMin + " 23:59:59" );
                    totalNum += recent.getCountNum();
                    map.get(recent.getFatherId()).setNoSyncNum(recent.getCountNum());
                }
            }
        }
        logger.info("[ProgramCheckTrigger][checkSyncData] totalNum: " + totalNum);
    }

    public void sendMail(String content) {
        List<ChannelConfig> configs = channelService.getConfig("PMailType");
        List<String> list = new ArrayList<String>();
        for (ChannelConfig temp : configs) {
            list.add(temp.getVal());
        }
        if (list.size() == 0) {
            logger.warn("[sendMail] no mail ");
            return;
        }
        String[] tos = list.toArray(new String[0]);
        SendMailUtils.send(PROGRAM_CHECK_TITLE, tos, content);
    }

    public void sendMsg(String content) {
        List<ChannelConfig> configs = channelService.getConfig("PMsgType");
        StringBuffer sb = new StringBuffer();
        int size = configs.size();
        for (int i = 0; i < size; i++) {
            if (i > 0) {
                sb.append(",");
            }
            sb.append(configs.get(i).getVal());
        }
        if (sb.length() == 0) {
            logger.warn("[sendMsg] no phone number");
            return;
        }
        SendMsgUtils.sendMsg(sb.toString(), content, "【epg】", "warn");
    }

}
